Technical Note TN2016

iTunes Visual Plug-ins



CONTENTS

このテクニカルノートはiTunes(バージョン1.1以降)のビジュアルプラグインの作り方を説明します。(iTunes 1.0はビジュアルプラグインをサポートしていません。)

このテクニカルノートで参照されているサンプルコードはすべてiTunes Visual Plug-ins SDKに含まれているます。iTunes Visual Plug-ins SDKは開発キットのページからダウンロードできます。

ビジュアルプラグインが完成したら、是非アップルコンピュータまでご一報下さい。ビジュアルプラグインに関する情報(英語のみ)はitunesvisuals@mac.comまでお送り下さい。ビジュアルプラグイン自体をお送りいただいてもかまいません。

 [2001年6月26日]






オーバービュ

iTunesのビジュアルエフェクトボタンをクリックすると、音楽のリズムに合わせて変化するグラフィックを鑑賞できます。

図1 ビジュアルエフェクトボタン

Mac OS 9やMac OS Xなどの異なるプラットフォームをサポートできるように、iTunesのプラグインは1つのエントリ関数を持った共有ライブラリとして実装されています。また、iTunesのプラグインはiTunesアプリケーション自体にリンクされません。プラグインが初期化される際にコールバック用の関数ポインタが提供されますので、iTunes APIへのアクセスはすべてこのコールバック関数経由で行います。

iTunesは様々な場面でビジュアルプラグインにメッセージを送信します。これらのメッセージはプラグインの初期化時と終了時、ユーザがビジュアルエフェクトを“入”または“切”にした時、ウインドウのサイズが変わった時、ユーザが音楽を再生または停止した時に送信されます。更にビジュアルエフェクト表示中はマウスイベント、キーボードイベント、ビジュアルエフェクトウインドウのアップデートイベントがビジュアルプラグインに送信されます。メッセージは後程詳しく解説します。

iTunesは再生されている音楽に合わせて、サウンドのサンプルデータと周波数データをビジュアルプラグインに送信します。プラグイン登録時には、プラグインが受け取るチャンネル数とデータの受信頻度を指定することができます。

プラグイン登録時にはアイドルメッセッジを受け取るかどうか指定することができます。アイドルメッセージは音楽が再生されているかどうかに関わらず、定期的に送信されます。例えば、音楽が停止した時にビジュアルエフェクトをゆっくりフェードアウトさせるようなことは、アイドルイベントを受け取ることで実現できます。

プラグインの環境設定はiTunesの環境設定ファイルに混在させることが可能です。iTunesはプラグインの環境設定にアクセスするためのAPIを提供しています。また、ユーザが“オプション”ボタンをクリックすると、iTunesはConfigureメッセージをアプリケーションに送信しますので、この時に環境設定ダイアログを表示するなどします。

iTunesのメッセージはすべてシステムタスクレベル(アプリケーションコードが実行するレベル)で送信されます。iTunes APIの各関数もシステムタスクレベルで呼び出さなければなりません。他のレベル(プリエンプティブタスクや遅延タスクなど)から呼び出すことはできません。実行レベルについてはテクニカルノート1104をご覧下さい。


先頭に戻る

プラグインの発見と登録プロセス

iTunesがプラグインをロードする時は、プラグインフォルダをリカーシブに検索します。Mac OS 9の場合、プラグインフォルダはiTunesアプリケーションと同じディレクトリにあります。Mac OS Xの場合、iTunesは‾/Library/iTunes/iTunes Plug-ins/と/Library/iTunes/iTunes Plug-ins/(ディレクトリが存在する場合のみ)を検索します。Mac OS 9の場合、iTunesはファイルタイプが‘hvpl’である共有ライブラリをビジュアルプラグインとして認識します。Mac OS Xの場合、iTunesはCFBundlePackageTypeが‘hvpl’と定義されているバンドル化されたプラグインをビジュアルプラグインとして認識します。このため、Mac OS 9とMac OS Xで動作するビジュアルプラグインは別々のバイナリが必要になります。プラグインは標準のアイコンを使用して下さい(プラグインのクリエータコードをiTunesのクリエータコードに合わせます。)

iTunes Visual Plug-in SDKに含まれているビジュアルプラグインのサンプルコードはMac OS 9とMac OS Xの2つの形式で提供されています。

プラグインライブラリは1つのエントリ関数をexportします。実際にexportされる関数名はプラグインのパッケージ形式によって異なります。プラグインが単一ファイルでCFMの共有ライブラリとして構成されている場合、エントリ関数はCFMのメインエントリ関数であれば、関数名は何でも構いません。一方、プラグインがバンドル化されたCFM形式である場合、エントリ関数は“iTunesPluginMain”でなければなりません。プラグインがバンドル化されたMach-O形式である場合、エントリ関数は“iTunesPluginMainMachO”でなければなりません。このエントリ関数を今後メインエントリポイントと呼びます。

iTunesがプラグインを発見すると、iTunesはそのプラグインのメインエントリポイントに対してkPluginInitMessageメッセージを送信します。単一ファイルのプラグインに複数のプラグインが入っている場合や、バンドル構成のプラグインに複数のプラグインが入っている場合、iTunesはkPluginInitMessageメッセージを一度しか送信しませんので、メッセージを受け取ったメインエントリポイントは自分の下にぶら下がっているプラグインにメッセージを伝える必要があります。

ビジュアルプラグインをiTunesに登録するためにはPlayerRegisterVisualPlugInを呼びます。PlayerRegisterVisualPlugInに渡すパラメータの1つは自分のビジュアルプラグインのメッセージハンドラ関数へのポインタです。kVisualPlugIn...で始まるメッセージはすべてこのメッセージハンドラ関数に送信されます。例えば、登録直後には、kVisualPluginInitMessageメッセージがメッセージハンドラ関数に送信されます。

プラグインを終了させる手続きは特に必要ありません。終了時はプラグインのメッセージハンドラ関数にkVisualPluginCleanupMessageメッセージが送信された後、プラグインのメインエントリポイントにkPluginCleanupMessageメッセージが送信されます。

iTunesの将来のバージョンと互換性を保つために、現在定義されていないメッセージを受け取った場合は、必ずunimpErrを返すようにして下さい。


先頭に戻る

メッセージ

1. プラグインのメインエントリポイントに送信されるメッセージ

以下のメッセージはビジュアルプラグインのメインエントリポイントに送信されます。ビジュアルプラグインのメインエントリポイントは次のように定義されています。

OSStatus main(OSType message, PluginMessageInfo * messageInfo, void * refCon);

message

メッセージの種類

messageInfo

メッセージパラメータへのポインタ(パラメータが無い場合もあります)

refCon

PluginInitMessage.refCon時に返した値です

このテーブルではプラグインのメインエントリポイントに送信されるメッセージの一覧と該当するPluginMessageInfoの種類を記述しています。パラメータを持たないメッセージは“n/a”となっています。このようなメッセージの場合はmessageInfoを無視します。

message messageInfo->u
kPluginInitMessage PluginInitMessage
kPluginCleanupMessage n/a
kPluginIdleMessage n/a

kPluginInitMessage

このメッセージは起動時にプラグインの共有ライブラリに送信されます。プラグインはここでPlayerRegisterVisualPlugInを呼び出して、iTunesに登録します。次に、PluginInitMessageのoptionsとrefconフィールドを記入して返します。

messageInfo->uは次のようにPluginInitMessageとなります

struct PluginInitMessage {
 UInt32       majorVersion; /* 入力 */
 UInt32       minorVersion; /* 入力 */

 void *       appCookie;    /* 入力 */
 ITAppProcPtr appProc;      /* 入力 */

 OptionBits   options;      /* 出力(プラグインが記入します) */
 void *       refCon;       /* 出力(プラグインが記入します) */
};

majorVersion minorVersion

現在実行しているiTunesアプリケーションが実装しているiTunes APIのバージョン番号

appCookie appProc

コールバックAPIに渡すパラメータ

options

ビジュアルプラグインはこのフィールドをゼロにします。optionsフィールドは現在デバイスプラグイン用に使用されています。

refCon

refconフィールドで返す値は、後程のメッセージ送信時のrefconパラメータに入ります

kPluginCleanupMessage

このメッセージはiTunes終了直前にプラグインに送信されます。

kPluginIdleMessage

ビジュアルプラグインでは使用しません。このメッセージはデバイスプラグイン用に設けてあります。アイドル処理を行うビジュアルプラグインは専用のkVisualPluginIdleMessageを使用して下さい。

2. Visual plug-in messages

ビジュアルプラグインのメッセージハンドラ関数は次のように定義されています。

OSStatus VisualPluginHandler(OSType message, 
  VisualPluginMessageInfo * messageInfo, void * refCon);

message

メッセージの種類

messageInfo

メッセージパラメータへのポインタ(パラメータが無い場合もあります)

refCon

VisualPluginInitMessage.refConで指定した値が入ります

このテーブルではビジュアルプラグインのメッセージハンドラ関数に送信されるメッセージの一覧と該当するVisualPluginMessageInfoの種類を記述しています。パラメータを持たないメッセージは“n/a”となっています。このようなメッセージの場合はmessageInfoを無視します。

message messageInfo->u
kVisualPluginInitMessage VisualPluginInitMessage
kVisualPluginCleanupMessage n/a
kVisualPluginIdleMessage n/a
kVisualPluginConfigureMessage n/a
kVisualPluginEnableMessage n/a
kVisualPluginDisableMessage n/a
kVisualPluginShowWindowMessage VisualPluginShowWindowMessage
kVisualPluginHideWindowMessage n/a
kVisualPluginSetWindowMessage VisualPluginSetWindowMessage
kVisualPluginRenderMessage VisualPluginRenderMessage
kVisualPluginUpdateMessage n/a
kVisualPluginPlayMessage VisualPluginPlayMessage
kVisualPluginChangeTrackMessage VisualPluginChangeTrackMessage
kVisualPluginStopMessage n/a
kVisualPluginSetPositionMessage VisualPluginSetPositionMessage
kVisualPluginPauseMessage n/a
kVisualPluginUnpauseMessage n/a
kVisualPluginEventMessage VisualPluginEventMessage

kVisualPluginInitMessage

このメッセージはPlayerRegisterVisualPluginでビジュアルプラグインを登録した直後に送信されます。このメッセージについてのみ、refConパラメータはPlayerRegisterVisualPluginMessage.registerRefConで指定した値が入ります。プラグインはVisualPluginInitMessageのoptionsとrefConフィールドを記入して返します。

messageInfo->u.visualPluginInitMessageは次のようにVisualPluginInitMessageとなります

struct VisualPluginInitMessage {
 UInt32       messageMajorVersion; /* 入力 */
 UInt32       messageMinorVersion; /* 入力 */
 NumVersion   appVersion;          /* 入力 */

 void *       appCookie;           /* 入力 */
 ITAppProcPtr appProc;             /* 入力 */

 OptionBits   options;             /* 出力(プラグインが記入します) */
 void *       refCon;              /* 出力(プラグインが記入します) */
};

messageMajorVersion
messageMinorVersion

現在実行しているiTunesアプリケーションが実装しているiTunes APIのバージョン番号

appVersion

現在実行しているiTunesアプリケーションのバージョン番号

appCookie
appProc

この2つのフィールドは後程iTunes APIを利用する際に必要になりますので、プラグイン内部で保持する必要があります。

options

現在定義されているオプションはありません。このフィールドはゼロに設定します。

refCon

このフィールドの値は、ビジュアルプラグインのメッセージハンドラに渡されます。プラグインはこの値を自由に使用できます。サンプルコードはこの値を使って、内部データへのポインタを保持しています。

kVisualPluginCleanupMessage

このメッセージはiTunes終了直前に送信されます。ビジュアルプラグインで使用しているリソース(メモリ、ファイルなど)はこの時に解除します。

kVisualPluginIdleMessage

このメッセージはアイドルメッセージを要求した場合のみ定期的に送信されます。アイドルメッセージを要求するには、PlayerRegisterVisualPluginMessage.optionsフィールドのkVisualWantsIdleMessagesを設定します。

kVisualPluginConfigureMessage

このメッセージはユーザがiTunesウインドウ右上の“オプション”ボタンをクリックした時に送信されます。オプションボタンはPlayerRegisterVisualPluginMessage.optionsフィールドでkVisualWantsConfigureを設定することによって使用可能となります。設定ダイアログの表示方法、リソースフォークの使い方、PlayerHandleMacOSEventの使い方などについてはサンプルコードをご覧下さい。

kVisualPluginEnableMessage

kVisualPluginDisableMessage

iTunesはすべてのビジュアルプラグインを使用可能にしますので、このメッセージに対してはnoErrを返します。

kVisualPluginShowWindowMessage

このメッセージはビジュアルエフェクトが実際に稼動した時に送信されます。ビジュアルエフェクトに必要なメモリ領域などはこの時に確保します。

messageInfo->u.showWindowMessageは次のようにVisualPluginShowWindowMessageとなります

struct VisualPluginShowWindowMessage {
 CGrafPtr   port;     /* 入力 */
 Rect       drawRect; /* 入力 */
 OptionBits options;  /* 入力 */
};

port

ビジュアルエフェクトを描画するためのポート。このパラメータは後程のrenderメッセージやupdateメッセージに含まれませんので、ビジュアルプラグイン側で値を保持しなければなりません。

drawRect

ビジュアルエフェクトを描画する範囲。このパラメータは後程のrenderメッセージやupdateメッセージに含まれませんので、ビジュアルプラグイン側で値を保持しなければなりません。

options

現在定義されているオプションはkWindowIsFullScreenのみです。kWindowIsFullScreenはiTunesがフルスクリーンモードで実行していることを示します。

kVisualPluginHideWindowMessage

このメッセージはビジュアルエフェクトが停止された時に送信されます。ビジュアルエフェクトで使用したメモリ領域などはこの時に解除します。

kVisualPluginSetWindowMessage

このメッセージはユーザがiTunesウインドウの大きさを変更した場合や、フルスクリーンモードを入/切した場合に送信されます。考え方としては、kVisualPluginHideWindowMessageに引き続き、kVisualPluginShowWindowMessageが送信された状態と同じですが、ビジュアルプラグインによっては、単一の切り替えメッセージが扱いやすいでしょう。

kVisualPluginRenderMessage

このメッセージは音楽再生中、登録時に指定した間隔で定期的に送信されます。

messageInfo->renderMessageは次のようにVisualPluginShowWindowMessageとなります

struct VisualPluginRenderMessage {
 RenderVisualData * renderData;  /* 入力 */
 UInt32             timeStampID; /* 入力 */
};

struct RenderVisualData {
 UInt8 numWaveformChannels;
 UInt8 waveformData[kVisualMaxDataChannels][kVisualNumWaveformEntries];

 UInt8 numSpectrumChannels;
 UInt8 spectrumData[kVisualMaxDataChannels][kVisualNumSpectrumEntries];
};

renderData->numWaveformChannels

サウンドサンプルデータのチャンネル数。ビジュアルプラグイン登録時に指定した値です。

renderData->waveformData

現在再生されているサウンドサンプルデータの上位8ビット。このパラメータの範囲は0から255まで、128が中心点(ACがゼロ)となります。

renderData->numSpectrumChannels

周波数データのチャンネル数。ビジュアルプラグイン登録時に指定した値です。

renderData->spectrumData

現在再生されているサウンドサンプルデータに512ポイントのFFTをかけた周波数データ。

kVisualPluginUpdateMessage

このメッセージはアップデートイベントがあった時に送信されます。ビジュアルプラグインは自分のポートを更新(描画)します。このメッセージはプラグインのウインドウが表示されている場合のみ(kVisualPluginShowWindowMessageメッセージが呼ばれてからkVisualPluginHideWindowMessageメッセージが呼ばれるまでの間)に送信されます。

kVisualPluginPlayMessage

このメッセージはiTunesが音楽トラックを再生した時に送信されます。ビジュアルエフェクトで音楽トラックの情報を表示する場合、ビジュアルプラグインはここで音楽トラックの情報を取得します。

messageInfo->u.playMessageは次のようにVisualPluginPlayMessageとなります

struct VisualPluginPlayMessage {
 ITTrackInfo *      trackInfo;   /* 入力 */
 ITStreamInfo *     streamInfo;  /* 入力 */
 SInt32             volume;      /* 入力 */

 UInt32             bitRate;     /* 入力 */

 SoundComponentData soundFormat; /* 入力 */
};

kVisualPluginChangeTrackMessage

このメッセージは音楽トラックの情報が変更された時に送信されます。例えば、ユーザが音楽トラックの情報を編集した場合や、異なるトラックを再生し始めた場合に送信されます。ビジュアルプラグインはここで音楽トラックの情報を更新します。

messageInfo->u.changeTrackMessageは次のようにVisualPluginChangeTrackMessageとなります

struct VisualPluginChangeTrackMessage {
 ITTrackInfo *      trackInfo;   /* 入力 */
 ITStreamInfo *     streamInfo;  /* 入力 */
};


kVisualPluginStopMessage

このメッセージは音楽の再生が停止された時に送信されます。

kVisualPluginSetPositionMessage

このメッセージは音楽トラックの経過時間が変わった時に送信されます。音楽トラックの経過時間を表示するようなビジュアルプラグインはこの値を使用します。

messageInfo->u.setPositionMessageは次のようにVisualPluginSetPositionMessageとなります

struct VisualPluginSetPositionMessage {
 UInt32 positionTimeInMS; /* 入力 */
};

kVisualPluginPauseMessage

kVisualPluginUnpauseMessage

iTunesは現在一時停止機能を停止と再生の組み合わせで実装しています。ビジュアルプラグインはこのメッセージに対してnoErrを返します。

kVisualPluginEventMessage

このメッセージはプラグインで処理可能なユーザイベントが発生した時に送信されます。ビジュアルプラグインでイベントを処理した場合はnoErrを返します。処理しなかった場合はunimpErrを返します。

messageInfo->u.eventMessageは次のようにVisualPluginEventMessageとなります

struct VisualPluginEventMessage {
 EventRecord * event; /* 入力 */
};

先頭に戻る

コールバックAPI

最初に述べた通り、プラグインはiTunesアプリケーションに直接リンクしません。そのかわり、iTunes APIはcookieパラメータとコールバック関数のポインタから成り立っているので、パラメータ管理やiTunes APIの呼び出しはすべてiTunesAPI.cのグルーコードに任せます。プラグインが必要とするcookieパラメータとコールバック関数は初期化時のメッセージで受け取ります。

OSStatus PlayerRegisterVisualPlugin (void *appCookie, ITAppProcPtr appProc,
   PlayerMessageInfo *messageInfo);

ビジュアルプラグインはkPluginInitMessageを受信した時にPlayerRegisterVisualPlugInを呼び出します。messageInfoパラメータはPlayerRegisterVisualPluginMessageで定義されている構造体を渡します。PlayerRegisterVisualPluginMessageの各フィルドの定義は次の通りです。

    /* PlayerRegisterVisualPluginMessage.options */

enum {
        /* kVisualPluginIdleMessageを受け取る場合設定します */
    kVisualWantsIdleMessages = (1L << 3),
    
        /* kVisualPluginConfigureMessageを受け取る場合設定します(オプション画面がある場合) */
    kVisualWantsConfigure    = (1L << 5)  
};


struct PlayerRegisterVisualPluginMessage {
        /* ビジュアルメニューに表れる名称。環境設定データの確認にも使用されます。 */
    Str63 name;
        /* オプション(上記enumをご覧下さい。) */
    OptionBits options;

        /* ビジュアルプラグインのクリエータコード。 */
    OSType creator;
    
        /* ビジュアルプラグインのバージョン番号。 */
    NumVersion pluginVersion;          

        /* ビジュアルプラグインのメッセージハンドラ関数へのポインタ */
    VisualPluginProcPtr handler;
    
        /* ビジュアルプラグインハンドラのRefCon値 */
    void *registerRefCon;

        /* 描画メッセージの間隔(ミリセカンド)
        (できるだけ頻繁にメッセージを受け取る場合は0xFFFFFFFFに設定します) */
    UInt32 timeBetweenDataInMS;    
                                             

    UInt32 numWaveformChannels; /* 0〜2 サンプルデータのチャンネル数 */
    UInt32 numSpectrumChannels; /* 0〜2 周波数データのチャンネル数 */

    SInt16 minWidth; /* 描画エリアの幅(最低値) */
    SInt16 minHeight; /* 描画エリアの高さ(最低値) */

    SInt16 maxWidth; /* 描画エリアの幅(最高値) */
    SInt16 maxHeight; /* 描画エリアの高さ(最高値) */

    UInt16 minFullScreenBitDepth;  /* 最低解像度(0の場合は指定無し) */
    UInt16 maxFullScreenBitDepth;  /* 最高解像度(0の場合は指定無し) */
        
        /* Reserved(ゼロにします) */
    UInt16 windowAlignmentInBytes; 
};



OSStatus PlayerIdle (
    void *appCookie,
    ITAppProcPtr appProc);
    

長時間かかるような処理を行う場合はPlayerIdleを呼び出して、iTunesに処理時間を与えます。


void PlayerShowAbout(
    void *appCookie,
    ITAppProcPtr appProc);

“iTunesについて...”ウインドウを表示します。


void PlayerOpenURL (
    void *appCookie,
    ITAppProcPtr appProc, 
    SInt8 * urlString,
    UInt32 length);

iTunesアプリケーションに特定のURLを開くよう指示します。urlStringパラメータはPascal形式でも、C形式の文字列でもありません。urlStringの長さはlengthパラメータで指定します。


OSStatus PlayerGetPluginData (
    void *appCookie, 
    ITAppProcPtr appProc,
    void *dataPtr,
    UInt32 dataBufferSize,
    UInt32 *dataSize);

ビジュアルプラグインの環境設定データをまとめてiTunesの環境設定ファイルから読み込みます。PlayerRegisterVisualPluginMessage.nameで指定した名称が環境設定データのキーとして使用されます。


OSStatus PlayerSetPluginData (
    void *appCookie, 
    ITAppProcPtr appProc,
    void *dataPtr,
    UInt32 dataSize);

ビジュアルプラグインの環境設定データをまとめてiTunesの環境設定ファイルに書き込みます。PlayerRegisterVisualPluginMessage.nameで指定した名称が環境設定データのキーとして使用されます。


OSStatus PlayerGetPluginNamedData (
    void *appCookie,
    ITAppProcPtr appProc,
    ConstStringPtr dataName,
    void *dataPtr,
    UInt32 dataBufferSize, 
    UInt32 *dataSize);

ビジュアルプラグインの環境設定データを部分的にiTunesの環境設定ファイルから読み込みます。PlayerRegisterVisualPluginMessage.nameで指定した名称とdataNameパラメータが環境設定データのキーとして使用されます。


OSStatus PlayerSetPluginNamedData (
    void *appCookie, 
    ITAppProcPtr appProc,
    ConstStringPtr dataName,
    void *dataPtr, 
    UInt32 dataSize);

ビジュアルプラグインの環境設定データを部分的にiTunesの環境設定ファイルに書き込みます。PlayerRegisterVisualPluginMessage.nameで指定した名称とdataNameパラメータが環境設定データのキーとして使用されます。


OSStatus PlayerHandleMacOSEvent (
    void *appCookie, 
    ITAppProcPtr appProc,
    const EventRecord *theEvent, 
    Boolean *eventHandled);

iTunesにMac OSイベントの処理を依頼します。サンプルコードでは、SettingsDialogFilterProcでPlayerHandleMacOSEventを使用しています。


OSStatus PlayerGetPluginFileSpec(
    void *appCookie,
    ITAppProcPtr appProc,
    FSSpec *pluginFileSpec);

ビジュアルプラグインのFSSpecを取得します。バンドル化されているビジュアルプラグインの場合、FSSpecはバンドルを指します。


OSStatus PlayerSetFullScreen (
    void *appCookie,
    ITAppProcPtr appProc,
    Boolean fullScreen);

iTunesのフルスクリーンモードを開始/終了します。スクリーンセーバのような働きをするプラグインはこの関数を使用します。


OSStatus PlayerSetFullScreenOptions (
    void *appCookie,
    ITAppProcPtr appProc,
    SInt16 minBitDepth,
    SInt16 maxBitDepth,
    SInt16 preferredBitDepth, 
    SInt16 desiredWidth,
    SInt16 desiredHeight);

フルスクリーンモード使用時の解像度と色数を指定します。独自のオプション設定ダイアログなどでユーザ操作によって解像度と色数が変更された場合は、登録時にPlayerRegisterVisualPlugInMessageで指定した値をここで変更できます。



先頭に戻る

参考文献

iTunes Visual plug-ins開発キット


先頭に戻る